<template>
  <div>
    <el-row class="drag">
      <el-col :span="22">SMSSC</el-col>
      <el-col :span="1">
        <i @click="isUnfold = !isUnfold" class="el-icon-setting no-drag"></i>
      </el-col>
      <el-col :span="1">
        <i @click="exit" class="el-icon-close no-drag"></i>
      </el-col>
    </el-row>
    <el-row id="login">
      <el-col :span="6">
        <div class="grid-content">
          <el-avatar shape="square" :size="100" fit="fill" src="static/header.png"></el-avatar>
        </div>
      </el-col>
      <el-col :span="18">
        <el-row>
          <el-col :offset="1" :span="23">
            <el-input v-model="username" placeholder="请输入用户名"></el-input>
          </el-col>
        </el-row>
        <el-row>
          <el-col :offset="1" :span="23">
            <el-input v-model="password" placeholder="请输入密码" show-password></el-input>
          </el-col>
        </el-row>
      </el-col>
      <el-col :span="18" :offset="3">
        <el-button
          size="small"
          class="login-btn"
          type="success"
          icon="el-icon-s-custom"
          @click="connectAndLogin"
          :disabled="isDisabled"
        >登录</el-button>
      </el-col>
      <el-col :span="24">
        <el-collapse-transition>
          <div v-show="isUnfold" id="unfold">
            <el-form label-width="100px">
              <el-form-item label="服务器地址">
                <el-input size="mini" v-model="bootstrap.socket.host"></el-input>
              </el-form-item>
              <el-form-item label="端口号">
                <el-input size="mini" v-model="bootstrap.socket.port"></el-input>
              </el-form-item>
              <el-form-item label="上传端口">
                <el-input size="mini" v-model="bootstrap.stream.port"></el-input>
              </el-form-item>
            </el-form>
          </div>
        </el-collapse-transition>
      </el-col>
    </el-row>
  </div>
</template>
<script>
const ipc = require("electron").ipcRenderer;
const fs = require("fs");
const remote = require("electron").remote;
const crypto = require("crypto");

import {
  MsgHeader,
  HeartBeat,
  MsgType,
  LoginReq,
  LoginResp,
  ConnectReq,
  ConnectResp
} from "../security_msg_pb";
import { ConnectEvent, LoginEvent } from "../smss_socket_event";
export default {
  created() {
    this.$nextTick(() => {
      fs.readFile("./data/bootstrap.json", (err, data) => {
        if (err) {
          return;
        }
        this.bootstrap = JSON.parse(data.toString());
        // 心跳保持事件
        this.$socket.on("timeout", () => {
          // flag  headerSize  header  msg
          //  4         4         n     m
          let heartBeat = new HeartBeat();
          heartBeat.setTimestamp(new Date().getTime());
          const heartBeatBuffer = heartBeat.serializeBinary();
          let msgHeader = new MsgHeader();
          msgHeader.setMsgSize(heartBeatBuffer.length);
          msgHeader.setMsgId(0);
          msgHeader.setMsgType(MsgType.HEART_BEAT);
          msgHeader.setFrom(this.$store.state.User.userID);
          msgHeader.setTo(0); // 发送给服务器
          const headerBuffer = msgHeader.serializeBinary();
          // 构造一个报文头
          let packageHeader = Buffer.alloc(8);
          packageHeader.write("AB47");
          packageHeader.writeInt32LE(headerBuffer.length, 4);
          // 合成报文
          const packageBuffer = Buffer.concat([
            packageHeader,
            headerBuffer,
            heartBeatBuffer
          ]);
          this.$socket.write(packageBuffer);
        });
        this.$socket.on("close", err => {
          this.isDisabled = false;
        });
      });
    });
  },
  data() {
    return {
      username: "",
      password: "",
      isUnfold: false,
      isDisabled: false,
      // 默认参数
      bootstrap: {
        socket: {
          host: "127.0.0.1",
          port: 8080,
          heartbeat: 10
        },
        stream: {
          port: 8081
        }
      }
    };
  },
  methods: {
    exit() {
      ipc.send("quit");
    },
    connectAndLogin() {
      if (this.username === "" || this.password === "") {
        return;
      }
      if (this.$socket.pending) {
        // 判断当前socket是否连接完成
        this.$socket.connect(
          this.bootstrap.socket.port,
          this.bootstrap.socket.host,
          () => {
            // 连接成功后将本地共享的用户数据初始化
            this.$store.commit("INIT_USER");
            // 连接成功后将连接信息保存到启动文件
            fs.writeFile(
              "./data/bootstrap.json",
              JSON.stringify(this.bootstrap, null, 2),
              err => {
                if (err) throw err;
                console.log("连接信息已保存");
              }
            );
            // 设置心跳间隔
            this.$socket.setTimeout(
              Number(this.bootstrap.socket.heartbeat) * 1000
            );
            // 确认连接-发送连接请求
            this.connect();
          }
        );
      } else {
        // 如果网络已经连接则直接登录
        this.login();
      }
    },
    login() {
      if (this.username === "" || this.password === "") {
        return;
      }
      new LoginEvent(
        this.$socket,
        this.$store.state.User.userID,
        this.username,
        this.password
      )
        .then(loginRes => {
          this.onLogined(loginRes);
        })
        .catch(err => {
          console.log(err);
        });
    },
    connect() {
      new ConnectEvent(this.$socket, this.$store.state.User.userID)
        .then(connectRes => {
          new LoginEvent(
            this.$socket,
            this.$store.state.User.userID,
            this.username,
            this.password
          )
            .then(loginRes => {
              this.onLogined(loginRes);
            })
            .catch(err => {
              console.log(err);
            });
        })
        .catch(err => {
          console.log(err);
        });
    },
    // 处理登录应答
    onLogined(loginResp) {
      // 判断登录信息是否正确
      if (LoginResp.LoginRespType.OK !== loginResp.getResp()) {
        console.log("用户名密码验证错误");
        // 回复登录按钮状态并清空用户名密码输入框
        this.isDisabled = false;
        this.username = "";
        this.password = "";
        return;
      }
      // 登录完成后服务器会返回 令牌、用户ID、用户别名、（通信私钥）
      this.$store.commit("SET_USER_TOKEN", loginResp.getToken());
      this.$store.commit("SET_USER_ALIAS", loginResp.getAlias());
      this.$store.commit("SET_USER_ID", loginResp.getId());
      // 判断是否需要更新用户文件
      fs.readFile("data/users.json", (err, data) => {
        let users;
        let hasAlias = false;
        if (err) {
          users = [];
        } else {
          users = JSON.parse(data.toString());
        }
        // 判断用户数据是否已经在用户文件中存在
        for (let i = 0; i < users.length; i++) {
          if (users[i]["alias"] === loginResp.getAlias()) {
            hasAlias = true;
          }
        }
        // 如果别名不存在则向用户文件中添加新项并更新文件
        if (!hasAlias) {
          users.push({ alias: loginResp.getAlias(), id: loginResp.getId() });
          fs.writeFile(
            "data/users.json",
            JSON.stringify(users, null, 2),
            err => {}
          );
        }
      });
      // 判断是否包含私钥数据，如果包含也需要保存到本地
      if (loginResp.getPrvKey() !== "") {
        fs.writeFile("./data/.shadow/mine.pem", loginResp.getPrvKey(), err => {
          if (err) throw err;
        });
      }
      // 界面跳转至聊天界面
      this.$router.push({ path: "/dialog" });
    }
  },
  watch: {
    isUnfold(val) {
      if (val) {
        remote.getCurrentWindow().setSize(430, 350);
      } else {
        setTimeout(() => {
          remote.getCurrentWindow().setSize(430, 220);
        }, 500);
      }
    }
  }
};
</script>
<style scoped>
.el-row {
  margin-bottom: 20px;
}
.bg-purple-dark {
  background: #99a9bf;
}
.bg-purple {
  background: #d3dce6;
}
.grid-content {
  border-radius: 4px;
  min-height: 100px;
}
.row-bg {
  padding: 10px 0;
  background-color: #f9fafc;
}
.login-btn {
  width: 100%;
}
.conf {
  margin-top: 5px;
}
.drag {
  -webkit-app-region: drag;
  margin-bottom: 0;
  background-color: rgba(52, 72, 161, 0.8);
  height: 40px;
  line-height: 40px;
  padding-right: 5px;
  border-radius: 5px 5px 0 0;
  color: white;
  padding-left: 10px;
}
.no-drag {
  -webkit-app-region: no-drag;
}
#login {
  background-color: rgb(235, 242, 249);
  padding: 18px 15px 10px 15px;
  border-radius: 0 0 5px 5px;
}
#unfold {
  margin-top: 17px;
  padding: 0 17px 0 5px;
}
.el-form-item {
  margin-bottom: 0;
}
</style>